package com.ete.service.service.location.geo

import android.Manifest
import android.os.Build
import com.amap.api.location.AMapLocation
import com.amap.api.location.AMapLocationClient
import com.amap.api.location.AMapLocationClientOption
import com.amap.api.location.AMapLocationListener
import com.amap.apis.utils.core.api.AMapUtilCoreApi
import com.blankj.utilcode.util.PermissionUtils
import com.blankj.utilcode.util.Utils
import com.ete.service.entry.location.LocationEntry
import com.ete.service.entry.location.LocationResult
import com.ete.service.manager.ManagerConstant
import com.ete.service.manager.location.LocationManager
import com.ete.service.service.R
import com.ete.service.service.location.ILocationListener
import com.ete.service.util.log.EteLog

/**
 * Author:LiXian
 * <p>
 * Desc:高德定位
 * Version:1.0
 * date 2025/4/21 11:32
 */
class GeoLocation : ILocationListener() {

    //权限
    private val mPermissions: Array<String> by lazy {
        val mPermissions = arrayOf(
                Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
        )
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            mPermissions.plus(Manifest.permission.FOREGROUND_SERVICE)
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            mPermissions.plus(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
        }
        mPermissions
    }

    //声明AMapLocationClient类对象
    private var mLocationClient: AMapLocationClient? = null

    private var mLocationCount = 0
    private var mLocationEntry: LocationEntry? = null
    private var mLocationResult: LocationResult? = null

    override fun initLocation(mEntry: LocationEntry) {
        this.mLocationEntry= mEntry
        mLocationCount = 0
        AMapLocationClient.updatePrivacyShow(Utils.getApp(), true, true)
        AMapLocationClient.updatePrivacyAgree(Utils.getApp(), true)
        AMapUtilCoreApi.setCollectInfoEnable(true)
        AMapUtilCoreApi.setCollectIPEnable(true)
        AMapLocationClient.setApiKey(mEntry.geoKey)
    }

    override fun startLocation(): Int {
        val checkCode = isCheckLocation()
        if (checkCode != ManagerConstant.CODE_SUCCESS) {
            return checkCode
        }
        return startGeoLocation()
    }

    override fun stopLocation() {
        mLocationClient?.stopLocation()
    }

    override fun destroyLocation() {
        stopLocation()
        mLocationEntry?.mCallback = null
        mLocationEntry = null

        mLocationClient?.unRegisterLocationListener(mLocationListener)
        mLocationClient?.stopLocation()
        mLocationClient?.onDestroy()
        mLocationClient = null
    }

    override fun getLocationResult(): LocationResult? {
        return mLocationResult
    }

    /**
     * 开始高德定位
     */
    private fun startGeoLocation(): Int {
        if (mLocationEntry?.geoKey.isNullOrEmpty()) {
            EteLog.d(LocationManager.TAG, "高德地图key为空")
            return ManagerConstant.CODE_NOT_GEO_KEY
        }
        if (mLocationClient == null) {
            mLocationClient = AMapLocationClient(Utils.getApp())
            mLocationClient?.stopLocation()
            mLocationClient?.setLocationOption(getLocationOption())
            mLocationClient?.setLocationListener(mLocationListener)
        }
        mLocationClient?.startLocation()
        EteLog.d(LocationManager.TAG, "开始高德地图定位")
        return ManagerConstant.CODE_SUCCESS
    }

    //定位回调监听
    private val mLocationListener: AMapLocationListener = AMapLocationListener {
        callbackGeoLocationResult(it)
    }

    /**
     * 返回高德定位结果
     */
    private fun callbackGeoLocationResult(mLocation: AMapLocation?) {
        EteLog.d(LocationManager.TAG, "返回高德定位结果mLocation:[$mLocation]")
        if (mLocation == null) return
        mLocationCount++
        val mResult = LocationResult()
        mResult.count = mLocationCount
        if (mLocation.errorCode == ManagerConstant.CODE_SUCCESS) {
            EteLog.d(LocationManager.TAG, "定位成功mLocation:[$mLocation]")
            mResult.code = ManagerConstant.CODE_SUCCESS
            mResult.result = Utils.getApp().getString(R.string.location_success)
            mResult.latitude = mLocation.latitude
            mResult.longitude = mLocation.longitude
            mResult.altitude = mLocation.altitude
            mResult.locationType = mLocation.locationType
            mResult.accuracy = mLocation.accuracy
            mResult.floor = mLocation.floor
            mResult.time = mLocation.time
            mResult.address = mLocation.address
            mResult.country = mLocation.country
            mResult.province = mLocation.province
            mResult.city = mLocation.city
            mResult.district = mLocation.district
            mResult.street = mLocation.street
            if (mLocationEntry?.isInterval != true) startGeoLocation()
        } else {
            EteLog.d(LocationManager.TAG, "定位失败mLocation:[$mLocation]")
            mResult.time = System.currentTimeMillis()
            mResult.latitude = 999.0
            mResult.longitude = 999.0
            mResult.code = mLocation.errorCode
            mResult.result = mLocation.errorInfo
            mLocationClient?.startLocation()
        }
        mLocationResult = mResult
        mLocationEntry?.mCallback?.invoke(mResult)
    }

    /**
     * 定位配置
     */
    private fun getLocationOption(): AMapLocationClientOption {
        return AMapLocationClientOption().apply {
            //定位模式：高精度模式
            locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy
            //优先使用GPS
            isGpsFirst = true
            if (mLocationEntry?.isInterval == true) {
                //连续定位
                interval = (mLocationEntry?.interval ?: 10) * 1000L
            } else {
                isOnceLocation = true
            }
            //设置定位请求超时时间，默认为30秒。
            httpTimeOut = (mLocationEntry?.timeout ?: 30) * 1000L
            //设置定位同时是否需要返回地址描述。
            isNeedAddress = mLocationEntry?.isDetailInfo ?: false
            //设置是否允许模拟软件Mock位置结果
            isMockEnable = false
            //设置是否开启定位缓存机制
            isLocationCacheEnable = false
            //设置语言
            geoLanguage = AMapLocationClientOption.GeoLanguage.DEFAULT
        }
    }

    /**
     * 检测定位权限
     */
    private fun isCheckLocation(): Int {
        val isGranted = PermissionUtils.isGranted(*mPermissions)
        if (!isGranted) {
            EteLog.d(LocationManager.TAG, "权限检测不通过")
            return ManagerConstant.CODE_NOT_PERMISSION
        }
        return ManagerConstant.CODE_SUCCESS
    }
}